#include <iostream>
#include <string>
#include <cstdlib>
#include <cstring>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#include <vector>

class EmailSender {
private:
    std::string smtpServer;
    int smtpPort;
    std::string username;
    std::string password;
    int sockfd;

    // 发送命令并接收响应
    bool sendCommand(const std::string& command, const std::string& expectedResponse) {
        std::cout << "发送: " << command;
        if (send(sockfd, command.c_str(), command.length(), 0) == -1) {
            std::cerr << "发送命令失败" << std::endl;
            return false;
        }

        char buffer[1024] = {0};
        int valread = read(sockfd, buffer, 1024);
        if (valread == -1) {
            std::cerr << "接收响应失败" << std::endl;
            return false;
        }
        std::string response(buffer);
        std::cout << "接收: " << response;

        if (response.find(expectedResponse) != 0) {
            std::cerr << "响应不符合预期" << std::endl;
            return false;
        }
        return true;
    }

public:
    EmailSender(const std::string& server, int port, const std::string& user, const std::string& pass)
        : smtpServer(server), smtpPort(port), username(user), password(pass), sockfd(-1) {}

    ~EmailSender() {
        if (sockfd != -1) {
            close(sockfd);
        }
    }

    bool connect() {
        struct hostent* host = gethostbyname(smtpServer.c_str());
        if (host == nullptr) {
            std::cerr << "无法解析SMTP服务器" << std::endl;
            return false;
        }

        sockfd = socket(AF_INET, SOCK_STREAM, 0);
        if (sockfd == -1) {
            std::cerr << "创建套接字失败" << std::endl;
            return false;
        }

        struct sockaddr_in serverAddr;
        serverAddr.sin_family = AF_INET;
        serverAddr.sin_port = htons(smtpPort);
        memcpy(&serverAddr.sin_addr, host->h_addr_list[0], host->h_length);

        if (::connect(sockfd, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) == -1) {
            std::cerr << "连接SMTP服务器失败" << std::endl;
            close(sockfd);
            sockfd = -1;
            return false;
        }

        char buffer[1024] = {0};
        int valread = read(sockfd, buffer, 1024);
        if (valread == -1 || std::string(buffer).find("220") != 0) {
            std::cerr << "SMTP服务器连接响应错误" << std::endl;
            close(sockfd);
            sockfd = -1;
            return false;
        }
        std::cout << "连接成功: " << buffer;
        return true;
    }

    bool authenticate() {
        if (!sendCommand("EHLO localhost\r\n", "250")) {
            std::cerr << "EHLO命令失败" << std::endl;
            return false;
        }

        if (!sendCommand("AUTH LOGIN\r\n", "334")) {
            std::cerr << "AUTH LOGIN命令失败" << std::endl;
            return false;
        }

        // Base64编码用户名和密码
        std::string encodedUsername = base64Encode(username);
        std::string encodedPassword = base64Encode(password);

        if (!sendCommand(encodedUsername + "\r\n", "334")) {
            std::cerr << "发送用户名失败" << std::endl;
            return false;
        }

        if (!sendCommand(encodedPassword + "\r\n", "235")) {
            std::cerr << "发送密码失败" << std::endl;
            return false;
        }

        return true;
    }

    bool sendEmail(const std::string& from, const std::string& to, const std::string& subject, const std::string& body) {
        if (!sendCommand("MAIL FROM:<" + from + ">\r\n", "250")) {
            std::cerr << "MAIL FROM命令失败" << std::endl;
            return false;
        }

        if (!sendCommand("RCPT TO:<" + to + ">\r\n", "250")) {
            std::cerr << "RCPT TO命令失败" << std::endl;
            return false;
        }

        if (!sendCommand("DATA\r\n", "354")) {
            std::cerr << "DATA命令失败" << std::endl;
            return false;
        }

        std::string emailData = "From: " + from + "\r\n";
        emailData += "To: " + to + "\r\n";
        emailData += "Subject: " + subject + "\r\n";
        emailData += "Content-Type: text/plain; charset=utf-8\r\n\r\n";
        emailData += body + "\r\n.\r\n";

        if (!sendCommand(emailData, "250")) {
            std::cerr << "发送邮件内容失败" << std::endl;
            return false;
        }

        return true;
    }

    void disconnect() {
        sendCommand("QUIT\r\n", "221");
        if (sockfd != -1) {
            close(sockfd);
            sockfd = -1;
        }
    }

    // Base64编码实现
    std::string base64Encode(const std::string& input) {
        static const std::string base64Chars = 
            "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

        std::string output;
        int val = 0;
        int valBits = -6;
        for (unsigned char c : input) {
            val = (val << 8) + c;
            valBits += 8;
            while (valBits >= 0) {
                output.push_back(base64Chars[(val >> valBits) & 0x3F]);
                valBits -= 6;
            }
        }
        if (valBits > -6) {
            output.push_back(base64Chars[((val << 8) >> (valBits + 8)) & 0x3F]);
        }
        while (output.size() % 4) {
            output.push_back('=');
        }
        return output;
    }
};

int main() {
    // 配置信息
    std::string smtpServer = "smtp.163.com";
    int smtpPort = 25; // 非SSL端口，SSL端口为465或994
    std::string username = "l1103426904@163.com"; // 你的163邮箱地址
    std::string password = "PQszZhT5skyj3jDA"; // 你的163邮箱授权码，不是登录密码

    // 邮件内容
    std::string from = "l1103426904@163.com";
    std::string to = "1103426904@qq.com";
    std::string subject = "测试邮件";
    std::string body = "这是一封由C++程序发送的测试邮件。\n\n问候，\n自动邮件系统";

    EmailSender sender(smtpServer, smtpPort, username, password);

    if (sender.connect()) {
        std::cout << "连接成功" << std::endl;
        if (sender.authenticate()) {
            std::cout << "认证成功" << std::endl;
            if (sender.sendEmail(from, to, subject, body)) {
                std::cout << "邮件发送成功" << std::endl;
            } else {
                std::cerr << "邮件发送失败" << std::endl;
            }
        } else {
            std::cerr << "认证失败" << std::endl;
        }
        sender.disconnect();
    } else {
        std::cerr << "连接失败" << std::endl;
    }

    return 0;
}    